package com.ycorn.auth.security;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ycorn.auth.entity.RolePermission;
import com.ycorn.auth.entity.User;
import com.ycorn.auth.entity.UserRole;
import com.ycorn.auth.mapper.*;
import com.ycorn.auth.util.SystemConstant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author: wujianmin
 * @Date: 2020/4/7 14:59
 * @Function:
 * @Version 1.0
 */
@Service
public class JdbcUserDetailServiceImpl implements UserDetailsService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private UserRoleMapper userRoleMapper;

    @Autowired
    private PermissionMapper permissionMapper;

    @Autowired
    private RolePermissionMapper rolePermissionMapper;

    @Autowired
    private CacheManager cacheManager;


    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 从缓存中获取userDetail
        Cache cache = cacheManager.getCache(SystemConstant.USER_DETAIL_CACHE_KEY);
        // 从缓存从取
        if (null != cache && null != cache.get(username)) {
            return (UserDetails) cache.get(username).get();
        }
        User user = userMapper.selectOne(Wrappers.<User>lambdaQuery().eq(User::getUsername, username));
        if (null == user) return null;
        List<UserRole> userRoles = userRoleMapper.selectList(Wrappers.<UserRole>lambdaQuery().eq(UserRole::getUserId, user.getId()));
        String[] permissions = userRoles.stream().map(role -> {
            List<RolePermission> rolePermissions = rolePermissionMapper.selectList(Wrappers.<RolePermission>lambdaQuery().eq(RolePermission::getRoleId, role.getRoleId()));
            return rolePermissions.stream().map(rp -> permissionMapper.selectById(rp.getPermissionId()).getCode()).collect(Collectors.toList());
        }).flatMap(Collection::stream).toArray(String[]::new);
        UserDetails userDetails = org.springframework.security.core.userdetails.User.builder()
                .password(user.getPassword())
                .username(user.getUsername())
                .authorities(permissions)
                .build();
        // 加入缓存
        cache.put(username, userDetails);
        return userDetails;
    }
}
